Code:
#include <stdio.h>
#include <stdlib.h>
#define WIN_32_LEAN_AND_MEAN
#include <windows.h>
/* Credit to : http://msdn.microsoft.com/en-us/library/windows/desktop/ms680582(v=vs.85).aspx */
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage
(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL
);
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
sprintf(lpDisplayBuf, "%s failed with error %d: %s", lpszFunction, (int)dw, (char *)lpMsgBuf);
MessageBox(NULL, lpDisplayBuf, "Error", MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
char * s_strdup( char * dest, char * string )
{
char * temp = NULL;
if ((temp = strrchr(string, '\n')))
*temp = '\0';
dest = malloc(strlen(string) + 1);
if ( !dest )
{
perror("Malloc");
exit(1);
}
return strcpy(dest, string);
}
int main( )
{
LPSTR username = NULL;
LPSTR password = NULL;
HANDLE hadmin_token;
HANDLE new_hadmin_token;
PHANDLE new_admin_token = &new_hadmin_token;
PHANDLE admin_token = &hadmin_token;
PROCESS_INFORMATION cmd_info;
LPPROCESS_INFORMATION pcmd_info = &cmd_info;
char buffer[BUFSIZ] = {0};
printf("Enter username to impersonate : ");
fgets(buffer, BUFSIZ, stdin);
username = s_strdup(username, buffer);
memset(buffer, 0, BUFSIZ);
printf("Enter %s's password : ", username);
fgets(buffer, BUFSIZ, stdin);
password = s_strdup(password, buffer);
memset(buffer, 0, BUFSIZ);
if ( !LogonUser(username, "", password, LOGON32_LOGON_NETWORK | LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, admin_token) )
ErrorExit("LogonUser");
if ( !ImpersonateLoggedOnUser( hadmin_token ) )
ErrorExit("ImpersonateLoggedOnUser");
DuplicateTokenEx(hadmin_token, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, new_admin_token );
if ( !CreateProcessAsUser(new_hadmin_token, "C:\\Windows\\System32\\cmd.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, "C:\\Windows\\System32\\cmd.exe", NULL, pcmd_info ))
ErrorExit("CreateProcessAsUser");
if ( !RevertToSelf() )
ErrorExit("RevertToSelf");
CloseHandle(hadmin_token);
CloseHandle(new_hadmin_token);
return 0;
}
I'm an administrator on my home computer, so in a way I don't need this. I was wondering though if I ever wanted to do this as a standard user, if I could somehow do that with CreateProcessAsUser(). I have the impersonation code right I think, but the function parameters for creating the process are way off.